/**
 * 
 */
package com.tio.live.main.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.tio.live.bs.api.Const;
import org.tio.live.bs.api.vo.topic.TopicVo;

import com.tio.live.main.api.UserServiceIntf;
import com.tio.live.main.dao.db02.ext.InviteCodeMapperExt;
import com.tio.live.main.dao.db02.ext.SrcPhoneMapperExt;
import com.tio.live.main.dao.db02.ext.UserMapperExt;
import com.tio.live.main.model.db02.LevelInfo;
import com.tio.live.main.model.db02.LevelInfoExample;
import com.tio.live.main.model.db02.SrcHead;
import com.tio.live.main.model.db02.SrcNick;
import com.tio.live.main.model.db02.Teacher;
import com.tio.live.main.model.db02.TeacherExample;
import com.tio.live.main.model.db02.User;
import com.tio.live.main.model.db02.UserExample;
import com.tio.live.main.model.db02.UserRole;
import com.tio.live.main.model.db02.vo.IpInfoVo;
import com.tio.live.main.model.db02.vo.SrcHeadVo;
import com.tio.live.main.model.db02.vo.SrcNickVo;
import com.tio.live.main.model.db02.vo.TeacherVo;
import com.tio.live.main.model.db02.vo.UserAuthVo;
import com.tio.live.main.model.db02.vo.UserBaseVo;
import com.tio.live.main.model.db02.vo.UserCoinVo;
import com.tio.live.main.model.db02.vo.UserDataVo;
import com.tio.live.main.model.db02.vo.UserExpVo;
import com.tio.live.main.model.db02.vo.UserRoleVo;
import com.tio.live.main.model.db02.vo.UserVo;
import com.tio.live.util.RobotUtil;
import com.tio.manager.core.dao.db.mybatis.MapperFactory;
import com.tio.manager.core.pager.Pageable;
import com.tio.manager.core.utils.ServiceUtils;
import com.tio.utils.ClearCacheUtils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;

/**
 * 用户表
 * 
 * @author: xufei
 */
@Component
@Transactional
public class UserService implements UserServiceIntf
{
	private static Logger log = LoggerFactory.getLogger(UserService.class);

	/**
	 * 
	 */
	public UserService()
	{

	}

	/**
	 * 
	 * @param userVo
	 * @return
	 */
	@Override
	public UserVo add(UserVo userVo)
	{
		UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
		mapper.insertSelective(userVo);
		return userVo;
		
	}

	/**
	 * 删除记录
	 * @param userVo
	 * @return
	 */
	@Override
	public int delete(UserVo userVo)
	{
		List<UserRole> userRoles = ServiceUtils.getBean(UserRoleService.class).selectRoleByUid(userVo.getId());
		if(userRoles == null || userRoles.isEmpty()) { 
			return 0;
		}
		
		//判断是否为主播
		//如果是主播
		
		return deleteByPrimaryKey(userVo.getId());
	}

	/**
	 * 根据主键删除记录
	 * @param id
	 * @return
	 */
	@Override
	public int deleteByPrimaryKey(Integer id)
	{
		UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
		int n = mapper.deleteByPrimaryKey(id);
		TopicVo topicVo = new TopicVo();
		topicVo.setType(TopicVo.Type.CLEAR_USER);
		topicVo.setParams(id + "");
		ClearCacheUtils.sendClearCacheTopic(topicVo);
		return n;
	}

	/**
	 * 批量删除
	 * @param ids
	 * @return
	 */
	@Override
	public int batchDelete(Integer[] ids)
	{
		int ret = 0;
		if (ids != null && ids.length > 0)
		{
			for (int i = 0; i < ids.length; i++)
			{
				ret += deleteByPrimaryKey(ids[i]);
			}
		}
		return ret;
	}

	/**
	 * 更新记录(默认情况下，有值没值的字段都会被更新，开发人员需要根据业务调整updateByPrimaryKey的sql语句)
	 * @param userVo
	 * @return
	 */
	@Override
	public int updateByPrimaryKey(UserVo userVo)
	{
		UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
		int n = mapper.updateByPrimaryKey(userVo);
		TopicVo topicVo = new TopicVo();
		topicVo.setType(TopicVo.Type.CLEAR_USER);
		topicVo.setParams(userVo.getId() + "");
		ClearCacheUtils.sendClearCacheTopic(topicVo);
		return n;
	}

	/**
	 * 只更新有值的字段，没有值的字段不更新
	 * -- 状态为注销时，delsign，修改为id
	 * @param userVo
	 * @return
	 */
	@Override
	public int updateByPrimaryKeySelective(UserVo userVo)
	{
		User oldUser = selectById(userVo.getId());
		
		if (Objects.equals(oldUser.getStatus(), Const.UserStandardStatus.LOGOUT)) {
			log.error("当前用户：{}已经被注销，不允许修改",oldUser.getId());
			return 0;
		}
		
		if(!Objects.equals(oldUser.getStatus(), userVo.getStatus())) {
			if (Objects.equals(userVo.getStatus(), Const.UserStandardStatus.LOGOUT)) {
				//若修改用户状态为注销 将对删除标识赋值为本用户ID
				userVo.setDelsign("L" + userVo.getId());
			}
			//查询讲师-应去除已注销的
			TeacherExample teacherExample = new TeacherExample();
			teacherExample.createCriteria().andStatusEqualTo(oldUser.getStatus()).andUidEqualTo(oldUser.getId())
			.andStatusNotEqualTo(Const.UserStandardStatus.LOGOUT);
			TeacherService teacherService = ServiceUtils.getBean(TeacherService.class);
			Teacher teacher = teacherService.selectOneByExample(teacherExample);
			if(teacher != null) {
				UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
				int n = mapper.updateByPrimaryKeySelective(userVo);
				TeacherVo update = new TeacherVo();
				update.setId(teacher.getId());
				update.setUid(userVo.getId());
				update.setStatus(userVo.getStatus());
				teacherService.updateByPrimaryKeySelective(update);
				return n;
			}
		}
		UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
		int n = mapper.updateByPrimaryKeySelective(userVo);
		TopicVo topicVo = new TopicVo();
		topicVo.setType(TopicVo.Type.CLEAR_USER);
		topicVo.setParams(userVo.getId() + "");
		ClearCacheUtils.sendClearCacheTopic(topicVo);
		return n;
	}

	/**
	 * 根据id选择记录
	 * @param id
	 * @return
	 */
	@Override
	public User selectById(Integer id)
	{
		UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
		User n = mapper.selectByPrimaryKey(id);
		return n;
	}

	/**
	 * 根据Example选择记录集
	 * @param userExample
	 * @return
	 */
	@Override
	public List<User> selectByExample(UserExample userExample)
	{
		UserMapperExt mapper = MapperFactory.getMapper(UserMapperExt.class);
		List<User> userList = mapper.selectByExample(userExample);
		return userList;
	}

	/**
	 * 根据Example选择一条记录
	 * @param userExample
	 * @return
	 */
	@Override
	public User selectOneByExample(UserExample userExample)
	{
		List<User> list = selectByExample(userExample);
		if (list == null || list.size() == 0)
		{
			return null;
		} else
		{
			if (list.size() > 1)
			{
				log.warn("你想选择一条记录，但有{}条记录", list.size());
			}
			return list.get(0);
		}
	}

	/**
	 * 查询表中所有记录
	 */
	@Override
	public List<User> queryAll() throws Exception
	{
		String sqlId = UserMapperExt.class.getName() + ".pageQuery";
		List<User> ret = ServiceUtils.queryListBean(sqlId, User.class, null);
		return ret;
	}

	/**
	 * 
	 * @param pageSize
	 * @param pageIndex
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public Pageable pageQuery(Integer pageSize, Integer pageIndex, Map<String, Object> params) throws Exception
	{
		if (pageSize == null)
		{
			pageSize = 10;
		}
		if (pageIndex == null)
		{
			pageIndex = 1;
		}
		String sqlId = UserMapperExt.class.getName() + ".pageAllInfoQuery";
		
		params.put("logout", Const.UserStandardStatus.LOGOUT);
		if (params != null)
		{
			//下面的代码根据实际情况修正  ---- start
			if (!StrUtil.isBlank((String) params.get("roomnum")))
			{
				params.put("roomnum", "%" + params.get("roomnum") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("ubase")))
			{
				params.put("ubase", "%" + params.get("ubase") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("domain")))
			{
				params.put("domain", "%" + params.get("domain") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("loginname")))
			{
				params.put("loginname", "%" + params.get("loginname") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("pwd")))
			{
				params.put("pwd", "%" + params.get("pwd") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("srcnick")))
			{
				params.put("srcnick", "%" + params.get("srcnick") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("invitecode")))
			{
				params.put("invitecode", "%" + params.get("invitecode") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("nick")))
			{
				params.put("nick", "%" + params.get("nick") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("avatar")))
			{
				params.put("avatar", "%" + params.get("avatar") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("avataralt")))
			{
				params.put("avataralt", "%" + params.get("avataralt") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("reghref")))
			{
				params.put("reghref", "%" + params.get("reghref") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("regchannel")))
			{
				params.put("regchannel", "%" + params.get("regchannel") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("remark")))
			{
				params.put("remark", "%" + params.get("remark") + "%");
			}
			if (!StrUtil.isBlank((String) params.get("delsign")))
			{
				params.put("delsign", "%" + params.get("delsign") + "%");
			}
			//上面的代码根据实际情况修正  ---- end
		}

		Pageable page = ServiceUtils.pageQuery(pageSize, pageIndex, true, sqlId, params);
		return page;
	}
	
	/**
	 * 创建
	 * @param num
	 * @return
	 * @throws Exception
	 * @author xufei
	 * @date 2018年7月4日 下午4:17:08
	 */
	@SuppressWarnings("unchecked")
	public String createRobot(Integer num) throws Exception {
		Pageable ipPage = ServiceUtils.getBean(IpInfoService.class).pageQuery(1, 1, null);
		if(ipPage == null || ipPage.getRecordCount() < 0) {
			return "ip信息有误";
		}
		List<IpInfoVo> ipInfoVos = (List<IpInfoVo>) ipPage.getData();
		IpInfoVo ipInfoVo = ipInfoVos.get(0);
		if(num <= 0) {
			return "创建机器数不能小于0";
		}
		Map<String, Object> params = new HashMap<>();
		params.put("status", Const.StandardStatus.DISABLED);
		Pageable<SrcHead> headPage = ServiceUtils.getBean(SrcHeadService.class).pageQuery(num, 1, params);
		List<SrcHead> srcHeads = (List<SrcHead>) headPage.getData();
		if(CollectionUtil.isEmpty(srcHeads) || srcHeads.size() != num) {
			return "头像资源位空,一次生成的数量大于头像库存";
		}
		Pageable<SrcNick> nickPage = ServiceUtils.getBean(SrcNickService.class).pageQuery(num, 1, params);
		List<SrcNick> srcNicks = (List<SrcNick>) nickPage.getData();
		if(CollectionUtil.isEmpty(srcNicks) || srcNicks.size() != num) {
			return "昵称资源不足";
		}
		LevelInfoService levelInfoService = ServiceUtils.getBean(LevelInfoService.class);
		SrcHeadService srcHeadService = ServiceUtils.getBean(SrcHeadService.class);
		SrcNickService srcNickService = ServiceUtils.getBean(SrcNickService.class);
		for(int i = 0; i < num ; i++) {
			int randomLevel = RobotUtil.getRandomLevel();
			LevelInfoExample levelInfoExample = new LevelInfoExample();
			levelInfoExample.createCriteria().andLevelEqualTo(randomLevel).andTypeEqualTo(Const.Role.NORMAL);
			LevelInfo levelInfo = levelInfoService.selectOneByExample(levelInfoExample);
			User user = createOneRobot(srcHeads.get(i).getHead(), srcNicks.get(i).getNick(), ipInfoVo, levelInfo);
			if(user == null) {
				throw new Exception("用户初始化错误");
			}
			//修改资源
			Integer uid = user.getId();
			SrcHeadVo srcUpdate = new SrcHeadVo();
			srcUpdate.setId(srcHeads.get(i).getId());
			srcUpdate.setUid(uid);
			srcUpdate.setUcount(srcHeads.get(i).getUcount() + 1);
			srcHeadService.updateByPrimaryKeySelective(srcUpdate);
			SrcNickVo srcNickVo = new SrcNickVo();
			srcNickVo.setUid(uid);
			srcNickVo.setStatus(Const.StandardStatus.NORMAL);
			srcNickVo.setId(srcNicks.get(i).getId());
			srcNickService.updateByPrimaryKeySelective(srcNickVo);
		}
		return "ok";
	}
	

	/**
	 * 创建机器人用户
	 * @param head
	 * @param nick
	 * @param ipInfoVo
	 * @param levelInfo
	 * @return
	 * @throws Exception
	 */
	public User createOneRobot(String head,String nick,IpInfoVo ipInfoVo,LevelInfo levelInfo) throws Exception {
		String phoneNum = RobotUtil.getPhoneCode();
		Map<String, Object> params = new HashMap<>();
		params.put("status", Const.StandardStatus.NORMAL);
		do {
			params.put("phone", phoneNum);
			String sqlId = SrcPhoneMapperExt.class.getName() + ".createPhoneNum";
			int update = ServiceUtils.update(sqlId, params);
			if(update > 0) {
				break;
			}
			phoneNum = RobotUtil.getPhoneCode();
		} while(true);
		
		String invCode = RobotUtil.getInviteCode();
		params.put("status", Const.StandardStatus.NORMAL);
		params.put("remark", "邀请码");
		do {
			params.put("id", invCode);
			String sqlId = InviteCodeMapperExt.class.getName() + ".createInvCode";
			int update = ServiceUtils.update(sqlId, params);
			if(update > 0) {
				break;
			}
			invCode = RobotUtil.getInviteCode();
		} while(true);
		
		
		//用户基本信息
		UserVo userVo = new UserVo();
		userVo.setLoginname(phoneNum);
		userVo.setAvatar(head);
		userVo.setPwd(SecureUtil.md5("${" + phoneNum + "}"));
		userVo.setRobot(Const.Robot.YES);
		userVo.setNick(nick);
		userVo.setIpid(ipInfoVo.getId());
		userVo.setSrcnick(nick);
		userVo.setInvitecode(invCode);
		userVo.setLevel(levelInfo.getLevel());
		userVo.setStatus(Const.UserStandardStatus.NORMAL);
		ServiceUtils.getBean(UserService.class).add(userVo);
		if(userVo.getId() == null) {
			return null;
		}
		Integer uid = userVo.getId();
		//用户基本信息
		UserBaseVo userBaseVo = new UserBaseVo();
		userBaseVo.setUid(uid);
		userBaseVo.setPhone(phoneNum);
		ServiceUtils.getBean(UserBaseService.class).add(userBaseVo);
		if(userBaseVo.getId() == null) {
			return null;
		}
		//用户财务
		UserCoinVo userCoinVo = new UserCoinVo();
		userCoinVo.setUid(uid);
		ServiceUtils.getBean(UserCoinService.class).add(userCoinVo);
		if(userCoinVo.getId() == null) {
			return null;
		}
		//用户角色
		UserRoleVo userRoleVo = new UserRoleVo();
		userRoleVo.setUid(uid);
		userRoleVo.setRid(Const.Role.NORMAL);
		userRoleVo.setStatus(Const.StandardStatus.NORMAL);
		ServiceUtils.getBean(UserRoleService.class).add(userRoleVo);
		if(userRoleVo.getId() == null) {
			return null;
		}
		//用户经验
		UserExpVo userExpVo = new UserExpVo();
		userExpVo.setUid(uid);
		userExpVo.setExp(levelInfo.getStartexp() + levelInfo.getLevel());
		ServiceUtils.getBean(UserExpService.class).add(userExpVo);
		if(userExpVo.getId() == null) {
			return null;
		}
		//用户认证
		UserAuthVo userAuthVo = new UserAuthVo();
		userAuthVo.setUid(uid);
		ServiceUtils.getBean(UserAuthService.class).add(userAuthVo);
		if(userAuthVo.getId() == null) {
			return null;
		}
		UserDataVo userDataVo = new UserDataVo();
		userDataVo.setUid(uid);
		ServiceUtils.getBean(UserDataService.class).add(userDataVo);
		return userVo;
	}
	
	
	public int regUser(DateTime dateTime) throws IOException {
		DateTime startTime = DateUtil.beginOfDay(dateTime);
		DateTime endTime = DateUtil.endOfDay(dateTime);
		String sqlId = UserMapperExt.class.getName() + ".regUser";
		Map<String, Object> params = new HashMap<>();
		params.put("starttime", startTime);
		params.put("endtime", endTime);
		try {
			List<Map<String, Object>> result = ServiceUtils.query(sqlId, params);
			if(CollectionUtil.isNotEmpty(result)) {
				Map<String, Object> countMap = result.get(0);
				int count = MapUtils.getIntValue(countMap, "regcount") ;
				return count;
			}
		} catch (Exception e) {
			log.error(e.getMessage(),e);
		}
		return 0;
	}
	
	
	/**
	 * 根据ID查询讲师信息---含直播标题 用户昵称  用户头像  用户账号
	 * @param id
	 * @return
	 * @throws IOException
	 */
	@Override
	public UserVo findUserByID(int id) throws IOException {
		String sqlId = UserMapperExt.class.getName() + ".findUserByID";
		Map<String, Object>params = new HashMap<>();
		params.put("status", Const.UserStandardStatus.NORMAL);
		params.put("id", id);
		UserVo userVo = ServiceUtils.selectBean(sqlId, UserVo.class, params);
		
		return userVo;
	}
	/**
	 * @author tanyaowu
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException
	{

	}
}
